package br.com.jk.master.processos;

import br.com.jk.util.StatusType.Status;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author camilo
 */
public class ProcessoTableModel extends AbstractTableModel {

  private static final long serialVersionUID = 1L;
  public static final int COLUNA_QTD = 3;
  public static final String COLUNA_NAME_ID = "Id";
  public static final String COLUNA_NAME_NUMERO_CHEQUE = "CHQ";
  public static final String COLUNA_NAME_VALOR = "Valor";
  public static final String COLUNA_NAME_MENSAGEM = "Mensagem";
  public static final String COLUNA_NAME_ORDEM = "";
  public static final String COLUNA_NAME_ANDAMENTO = "";
  public static final String COLUNA_NAME_STATUS = "Status";
  public static final String COLUNA_NAME_OBSERVACAO = "Observação";
  public static final String COLUNA_NAME_NUM_DOCUMENTO = "Nº Doc.";
  public static final String COLUNA_NAME_CLIENTE = "Cliente";
  public static final String COLUNA_NAME_FORNECEDOR = "Fornecedor";
  public static final String COLUNA_NAME_CONTA_BANCO = "Conta";
  public static final String COLUNA_NAME_MOVIMENTO_TIPO = "Tipo";
  public static final int COLUNA_COD_DATA_PREVISAO = 0;
  public static final int COLUNA_COD_DATA_LANCAMENTO = 1;
  public static final int COLUNA_COD_PROGRESS_BAR = 2;
  public static final int COLUNA_COD_VALOR = 3;
  public static final int COLUNA_COD_NUM_DOCUMENTO = 4;
  public static final int COLUNA_COD_STATUS = 5;
  public static final int COLUNA_COD_CONTA_BANCO = 6;
  public static final int COLUNA_COD_MOVIMENTO_TIPO = 7;
  public static final int COLUNA_COD_CLIENTE = 8;
  public static final int COLUNA_COD_FORNECEDOR = 9;
  public static final int COLUNA_COD_NUM_CHEQUE = 10;
  public static final int COLUNA_COD_OBSERVACAO = 11;
  public static final int COLUNA_COD_ID = 12;
  public static final int COLUNA_COD_ID_CLIENTE = 13;
  public static final int COLUNA_COD_ID_FORNECEDOR = 14;
  public static final int COLUNA_COD_ID_CONTA_BANCO = 15;
  public static final int COLUNA_COD_ID_MOVIMENTO_TIPO = 16;
  /**
   * Essa lista armazenará os objetos atualmente exibidos na tabela.
   */
  private List<Processo> lstMaster;

  /**
   * Constutor que simplesmente instancia o nosso {@link List} que usaremos para guardar os valores.
   */
  public ProcessoTableModel() {
    // no construtor, instanciamos o List  
    lstMaster = new ArrayList<>();
  }

  /**
   * Criamos um construtor de conveniência para já popular a lista.
   *
   * @param lista a lista de produtos a ser adicionada.
   */
  public ProcessoTableModel(List<Processo> lista) {
    this();
    lstMaster.addAll(lista);
  }

  // ==============================================================  
  // Métodos implementados.  
  // ==============================================================  
  /**
   * Aqui configura-se o tipo de dados que serão apresentados por coluna
   *
   * Use o código abaixo para definir todas as colunas com o mesmo tipo de dados.<br /><br />
   * <i>return "TIPO".class;</i>
   *
   * @param coluna
   * @return
   */
  @Override
  public Class<?> getColumnClass(int coluna) {
    switch (coluna) {
      case COLUNA_COD_DATA_LANCAMENTO:
        return JOptionPane.class;
      case COLUNA_COD_PROGRESS_BAR:
        return Integer[].class;
      case COLUNA_COD_DATA_PREVISAO:
        return Integer.class;
      case COLUNA_COD_NUM_CHEQUE:
        return Integer.class;
      case COLUNA_COD_NUM_DOCUMENTO:
        return Integer.class;
      case COLUNA_COD_STATUS:
        return Status.class;
      case COLUNA_COD_VALOR:
        return BigDecimal.class;
      default:
        return String.class;
    }
  }

  /**
   * Retorna a quantidade de colunas da tabela.
   *
   * @return
   */
  @Override
  public int getColumnCount() {
    return COLUNA_QTD;
  }

  /**
   * Retorna o nome de cada coluna
   *
   * @param coluna
   * @return
   */
  @Override
  public String getColumnName(int coluna) {
    switch (coluna) {
      case COLUNA_COD_NUM_CHEQUE:
        return COLUNA_NAME_NUMERO_CHEQUE;
      case COLUNA_COD_VALOR:
        return COLUNA_NAME_VALOR;
      case COLUNA_COD_DATA_LANCAMENTO:
        return COLUNA_NAME_MENSAGEM;
      case COLUNA_COD_PROGRESS_BAR:
        return COLUNA_NAME_ANDAMENTO;
      case COLUNA_COD_DATA_PREVISAO:
        return COLUNA_NAME_ORDEM;
      case COLUNA_COD_NUM_DOCUMENTO:
        return COLUNA_NAME_NUM_DOCUMENTO;
      case COLUNA_COD_STATUS:
        return COLUNA_NAME_STATUS;
      case COLUNA_COD_CONTA_BANCO:
        return COLUNA_NAME_CONTA_BANCO;
      case COLUNA_COD_MOVIMENTO_TIPO:
        return COLUNA_NAME_MOVIMENTO_TIPO;
      case COLUNA_COD_CLIENTE:
        return COLUNA_NAME_CLIENTE;
      case COLUNA_COD_FORNECEDOR:
        return COLUNA_NAME_FORNECEDOR;
      case COLUNA_COD_OBSERVACAO:
        return COLUNA_NAME_OBSERVACAO;
      default:
        return "";
    }
  }

  /**
   * Retorna a quantidade de linhas da tabela.
   *
   * @return
   */
  @Override
  public int getRowCount() {
    return lstMaster.size();
  }

  /**
   * Retorna o valor de determinada célula.
   *
   * @param linha
   * @param coluna
   * @return
   */
  @Override
  public Object getValueAt(int linha, int coluna) {
//    Cria-se um objeto com base na linha solicitada
    Processo obj = lstMaster.get(linha);

    switch (coluna) {
      /*case COLUNA_COD_ID:
       return obj.getAndamentoFinal();
       case COLUNA_COD_NUM_CHEQUE:
       return obj.getAndamentoProgresso();
       case COLUNA_COD_VALOR:
       return obj.getDescricao();*/
      case COLUNA_COD_DATA_LANCAMENTO:
        return obj.getMensagem();
      case COLUNA_COD_DATA_PREVISAO:
        return obj.getOrdem();
      case COLUNA_COD_PROGRESS_BAR:
        return obj.getAndamento();
      /* case COLUNA_COD_ID_FORNECEDOR:
       return obj.getFornecedor().getId();
       case COLUNA_COD_ID_CLIENTE:
       return obj.getCliente().getId();
       case COLUNA_COD_NUM_DOCUMENTO:
       return obj.getNumDocumento();
       case COLUNA_COD_STATUS:
       return obj.getStatus();
       case COLUNA_COD_CONTA_BANCO:
       return obj.getContaBanco().getConta();
       case COLUNA_COD_MOVIMENTO_TIPO:
       return obj.getMovimentoTipo().getDescricao();
       case COLUNA_COD_CLIENTE:
       return obj.getCliente().getFantasia();
       case COLUNA_COD_FORNECEDOR:
       return obj.getFornecedor().getFantasia();
       case COLUNA_COD_OBSERVACAO:
       return obj.getObservacao();
       case COLUNA_COD_ID_CONTA_BANCO:
       return obj.getContaBanco().getId();
       case COLUNA_COD_ID_MOVIMENTO_TIPO:
       return obj.getMovimentoTipo().getId();*/
      default:
        return null; // não ocorrerá devido a quantidade de colunas
    }
  }

  /**
   * Define as células que poderão ser editadas.
   *
   * @param rowIndex
   * @param columnIndex
   * @return
   */
  @Override
  public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false;
  }

  /**
   * Define o valor para a célula da tabela
   *
   * @param valor - Novo valor para a célula
   * @param linha - Linha onde está a célula a ser alterada
   * @param coluna Coluna onde está a célula a ser alterada
   */
  @Override
  public void setValueAt(Object valor, int linha, int coluna) {
//    Cria-se um objeto com base na linha solicitada
    Processo obj = lstMaster.get(linha);
//verifica-se qual será a coluna a ser alterada
    switch (coluna) {
      /*case COLUNA_COD_ID:
       obj.setAndamentoFinal(Integer.parseInt(valor.toString()));
       break;
       case COLUNA_COD_NUM_CHEQUE:
       obj.setAndamentoProgresso(Integer.parseInt(valor.toString()));
       break;*/
      case COLUNA_COD_VALOR:
        obj.setDescricao(valor.toString());
        break;
      case COLUNA_COD_DATA_LANCAMENTO:
        obj.setMensagem(valor.toString());
        break;
      case COLUNA_COD_DATA_PREVISAO:
        obj.setOrdem(Integer.parseInt(valor.toString()));
        break;
      case COLUNA_COD_PROGRESS_BAR:
        Integer[] prog = (Integer[]) valor;
        obj.setAndamento(prog);
        break;
      /*case COLUNA_COD_ID_FORNECEDOR:
       obj.getFornecedor().setId(Integer.parseInt(valor.toString()));
       break;
       case COLUNA_COD_ID_CLIENTE:
       obj.getCliente().setId(Integer.parseInt(valor.toString()));
       break;
       case COLUNA_COD_NUM_DOCUMENTO:
       obj.setNumDocumento(Integer.parseInt(valor.toString()));
       break;
       case COLUNA_COD_STATUS:
       obj.setStatus(Status.valueOf(valor.toString()));
       break;
       case COLUNA_COD_CONTA_BANCO:
       obj.getContaBanco().setConta(valor.toString());
       break;
       case COLUNA_COD_MOVIMENTO_TIPO:
       obj.getMovimentoTipo().setDescricao(valor.toString());
       break;
       case COLUNA_COD_CLIENTE:
       obj.getCliente().setFantasia(valor.toString());
       break;
       case COLUNA_COD_FORNECEDOR:
       obj.getFornecedor().setFantasia(valor.toString());
       break;
       case COLUNA_COD_OBSERVACAO:
       obj.setObservacao(valor.toString());
       break;
       case COLUNA_COD_ID_CONTA_BANCO:
       obj.getContaBanco().setId(Integer.parseInt(valor.toString()));
       break;
       case COLUNA_COD_ID_MOVIMENTO_TIPO:
       obj.getMovimentoTipo().setId(Integer.parseInt(valor.toString()));
       break;*/
    }

    // é importante notificar os listeners a cada alteração  
    fireTableDataChanged();
  }

  // ==============================================================  
  // Até aqui seria o mínimo necessário para um TableModel funcional, mas  
  // ainda não há métodos para adicionar, remover ou resgatar objetos. Vamos  
  // criá-los.  
  // ==============================================================  
  /**
   * Similar ao {@link #adiciona()}, porém para remover. Recebe o índice do registro a ser removido.
   * Se não souber o índice, use o método {@link #getIndice()} antes.
   */
  public void remove(int indice) {
    lstMaster.remove(indice);
    fireTableRowsDeleted(indice, indice);
  }

  /**
   * Retorna o índice de determinado registro.
   */
  public int getIndice(Processo m) {
    return lstMaster.indexOf(m);
  }

  /**
   * Adiciona todos os registros na lista à este modelo.
   */
  public void adicionaLista(List<?> lista) {
    int i = getRowCount();
    lstMaster.addAll((List<Processo>) lista);
    fireTableRowsInserted(i, getRowCount() - 1);
  }

  /**
   * Adiciona um novo registro e notifica os listeners que um novo registro foi adicionado.
   */
  public void adiciona(Processo classe) {
    lstMaster.add((Processo) classe);
    // informamos os listeners que a linha (size - 1) foi adicionada  
    fireTableRowsInserted(lstMaster.size() - 1, lstMaster.size() - 1);
  }

  /**
   * Esvazia a lista.
   */
  public void limpaLista() {
    int i = lstMaster.size();
    lstMaster.clear();
    fireTableRowsDeleted(0, i - 1);
  }
}
